/**
 * ========================================================
 * 北京五八信息技术有限公司技术中心开发一部
 * 日 期：2011-6-2 下午02:19:09
 * 作 者：张纪豪
 * 版 本：1.0.0
 * ========================================================
 * 修订日期                        修订人                     描述
 *
 */

package com.bj58.migrate.helper;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPOutputStream;


/**
 * 功能描述：辅助工具
 * 
 * @author howsun(howsun.zhang@google.com)
 * @version 1.0.0
 */
public abstract class Helper {

	private static String currentPath;

	//private static String MY_NAME_SPACE_PATH = "/bj58config/%s/";
	private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(Helper.class);
	private static final Map<String, File> PATHS = new HashMap<String, File>();

	/**
	 * 按如下优先级搜索：<br>
	 * 1、在${当前盘符}/bj58config/${namespace}/下搜索<br>
	 * 2、在类路径下搜索，通常为src/...<br>
	 * 3、在当前工程目录下搜索<br>
	 * 
	 * @param fileName
	 * @return
	 */
	public static File seekFile(String fileName){

		File result = PATHS.get(fileName);

		if(result == null){

			while(true){
				
				// 默认查找usp路径(1.4版本)
//				try {
//					result = getFile(new File(WF.getConfigFolder() + WF.getNamespace()), fileName);
//					if(result != null){
//						break;
//					}
//				} catch (Exception e) {
//					log.error("默认查找usp路径scf发生异常：", e);
//				}
				
				
				//1、在${当前盘符}/bj58config/${namespace}/下搜索，
				File namespace = NameSpaceUtil.getConfigFolder();
				if(namespace != null){
					log.info("h1:"+namespace.getPath()+"."+fileName);
					result = getFile(namespace, fileName);
					if(result != null){
						break;
					}
				}


				//2、在类路径下获取
				ClassLoader classLoader = Helper.class.getClassLoader();
				URL url = classLoader.getResource("META-INF");
				if(url != null){
					log.info("h2"+url.getPath());
					File file = new File(url.getPath());
					if(file.exists()){
						result = getFile(file, fileName);
						if(result != null){
							break;
						}
					}
				}

				url = classLoader.getResource("");
				if(url != null){
					File file = new File(url.getPath());
					log.info("h3"+url.getPath());
					if(file.exists()){
						result = getFile(file, fileName);
						if(result != null){
							break;
						}
					}
				}


				//3、在工程目录下搜索
				result = getFile(new File(System.getProperty("user.dir")), fileName);
				if(result != null && result.exists()){
					log.info("h4"+result.getPath());
					break;
				}

				result = getFile(new File(getCurrentPath()), fileName);
				if(result != null && result.exists()){
					log.info("h5"+result.getPath());
					break;
				}

				break;
			}

			if(result != null){
				PATHS.put(fileName, result);
			}
		}

		return result;

	}


	/**
	 * 在参数1为根的目录下搜索参数2指定的文件
	 * @param root
	 * @param fileName
	 * @return
	 */
	public static File getFile(File root, String fileName){
		if(root.isDirectory()){
			File[] files = root.listFiles();
			for(File f : files){
				File found = getFile(f, fileName);
				if(found != null){
					return found;
				}
			}
		}
		return fileName.equalsIgnoreCase(root.getName()) ? root : null;
	}

	/**
	 * 获取包所在的目录
	 * @return
	 */
	public static String getCurrentPath() {

		if(currentPath == null) {
			try {
				Class<?> caller = getCaller();
				if(caller == null) {
					caller = Helper.class;
				}
				currentPath = caller.getProtectionDomain().getCodeSource().getLocation().getPath();
			} catch (Exception ex) {
				currentPath = System.getProperty("user.dir");
				return currentPath;
			}

			File file = new File(currentPath);

			if(file.exists()){
				currentPath = file.isDirectory() ? file.getPath() : file.getParentFile().getPath();
			}
			else{
				currentPath = currentPath.replaceFirst("file:/", "");
				currentPath = currentPath.replaceAll("!/", "");
				currentPath = currentPath.replaceAll("\\\\", "/");
				currentPath = currentPath.substring(0, currentPath.lastIndexOf("/"));

				if(currentPath.startsWith("/")){
					String osName = System.getProperty("os.name").toLowerCase();
					if(osName.indexOf("window") >=0){
						currentPath = currentPath.substring(1);
					}
				}
			}
		}

		return currentPath;
	}


	/**
	 * 获取调用者
	 * @return
	 */
	public static Class<?> getCaller() {

		StackTraceElement stack[] = (new Throwable()).getStackTrace();

		if(stack.length < 3) {
			return Helper.class;
		}

		String className = stack[2].getClassName();
		try {
			return Class.forName(className);
		} catch (ClassNotFoundException e) {
			System.out.println(String.format("%s类未找到", className));
			//log.info(String.format("%s类未找到", className), e);
		}
		return null;
	}


	/**
	 * 根据装载的类获取该类所在的物理路径
	 * @param cls
	 * @return
	 */
	public static String getCurrentPath(Class<?> cls) {
		String path = cls.getProtectionDomain().getCodeSource().getLocation().getPath();
		path = path.replaceFirst("file:/", "");
		path = path.replaceAll("!/", "");
		path = path.substring(0, path.lastIndexOf("/"));
		if(path.substring(0,1).equalsIgnoreCase("/")){
			String osName = System.getProperty("os.name").toLowerCase();
			if(osName.indexOf("window") >=0){
				path = path.substring(1);
			}
		}
		return path;
	}

	public static File getRoot(File file){
		return file.getParentFile() == null ? file : getRoot(file.getParentFile());
	}

	/**
	 * 获取Helper类或其jar包的物理路径根目录
	 * @return
	 */
	public static File getRoot(){
		return getRoot(new File("/").getAbsoluteFile());
	}

	/**
	 * 判断字符串是否为空
	 * @param src
	 * @return
	 */
	public static boolean hasLength(String src){
		return src != null && src.trim().length() > 0;
	}


	/**
	 * Compressed stream, saving transmission resources
	 * @return
	 */
	public static String compressStream(String src){
		if(!hasLength(src)){return src;}
		ByteArrayOutputStream baos = null;
		GZIPOutputStream gzip = null;
		try {
			baos = new ByteArrayOutputStream();
			gzip  = new GZIPOutputStream(baos);
			gzip.write(src.getBytes("UTF-8"));
			gzip.finish();
			return new sun.misc.BASE64Encoder().encodeBuffer(baos.toByteArray());
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			if(gzip != null){try {gzip.close();} catch (Exception e2) {}}
			if(baos != null){try {baos.close();} catch (Exception e2) {}}
		}
		return src;
	}

	public static void main(String[] args) throws Exception {
		System.out.println(getCurrentPath());
	}
}
